<template>
  <el-form-item :rules="item.rule" :label="item.label" :prop="item.prop">
    <div class="content">
      <div v-if="item.searcher" class="search">
        <el-select
          v-if="item.searcher.showSelect"
          v-model="selectModel"
          placeholder="请选择"
          clearable
          :filterable="item.searcher.filterable"
          :style="{ width: item.searcher.showInput ? '40% ' : '100%' }"
          @change="selectChange(item.dataSource)"
        >
          <!--          :style="{ width: item.searcher.width || '120px' }"-->
          <el-option
            v-for="child in item.searcher.children"
            :label="child.label"
            :value="child.code"
            :key="child.code"
          ></el-option>
        </el-select>
        <el-input
          v-if="item.searcher.showInput"
          prefix-icon="el-icon-search"
          v-model="inputModel"
          :placeholder="item.searcher.inputPlaceholder || '请输入'"
          clearable
          @input="inputChange"
        ></el-input>
      </div>
      <el-transfer
        :class="{ searcher: item.searcher }"
        style="width:100%;"
        :filterable="item.filterable || true"
        :props="{
          key: 'code',
          label: 'label'
        }"
        v-model="formData[item.prop]"
        :titles="item.titles || ['Source', 'Target']"
        :format="{
          noChecked: '${total}',
          hasChecked: '${checked}/${total}'
        }"
        :button-texts="item.buttonTexts || []"
        :data="sourceData"
        :left-default-checked="item.leftDefaultChecked"
        :right-default-checked="item.rightDefaultChecked"
        @change="change"
        @mouseover.native="showTooltip"
      >
        <div class="pagination" slot="left-footer" v-if="isPagination">
          <el-button
            class="transfer-footer"
            type="primary"
            size="medium"
            @click="leftToPage('pre')"
            plain
            >上一页</el-button
          >
          <el-button
            class="transfer-footer"
            type="primary"
            size="medium"
            @click="leftToPage('next')"
            plain
            >下一页</el-button
          >
        </div>
      </el-transfer>
    </div>
  </el-form-item>
</template>

<script>
import _ from "lodash";
import Message from "../../utils/Messager";

export default {
  name: "transferCom",
  props: {
    item: {
      type: Object,
      default: () => {
        return {};
      }
    },
    formData: {
      type: Object,
      default: () => {
        return {};
      }
    }
  },
  data() {
    return {
      selectModel: "",
      inputModel: "",
      //分页数据源
      sourceData: [],
      //全部数据源
      allSourceData: [],
      //右侧选中的数据对象
      rightSourceData: [],
      currentPage: 1,
      pageSize: 200,
      isLastPage: false
    };
  },
  methods: {
    searchMethod({ query, item }) {
      if (
        this.item.filterMethod &&
        typeof this.item.filterMethod == "function"
      ) {
        this.item.filterMethod({ query, item });
      }
    },
    change(codes, to, data) {
      if (!this.isPagination) return;
      if (to == "right") {
        for (let code of codes) {
          const index = this.allSourceData.findIndex(item => {
            return item.code == code;
          });
          if (index > -1) {
            this.rightSourceData.push(this.allSourceData[index]);
            this.allSourceData.splice(index, 1);
          }
        }
        this.rightSourceData = _.uniqBy(this.rightSourceData, "code");
      } else if (to == "left") {
        for (let code of data) {
          const index = this.rightSourceData.findIndex(selectData => {
            return code == selectData.code;
          });
          if (index > -1) {
            this.rightSourceData.splice(index, 1);
          }
        }
      }
      if (this.item.change && typeof this.item.change == "function") {
        return this.item.change();
      }
    },
    selectChange(dataSource) {
      if (this.selectModel == "") {
        return;
      }
      this.search(dataSource);
    },
    inputChange: _.debounce(function() {
      this.search();
    }, 2000),
    search(dataSource) {
      if (
        this.item.searcher.search &&
        typeof this.item.searcher.search == "function"
      ) {
        return this.item.searcher.search({
          selectModel: this.selectModel,
          inputModel: this.inputModel,
          dataSource: dataSource
        });
      }
    },
    cleanSourceData() {
      // console.log(this.allSourceData.length);
      for (let i = 0; i < this.rightSourceData.length; i++) {
        const item = this.rightSourceData[i];
        const index = this.allSourceData.findIndex(value => {
          return item.code == value.code;
        });
        if (index > -1) {
          this.allSourceData.splice(index, 1);
        }
      }
      // console.log(this.allSourceData.length);
    },
    setDataSource() {
      //分页处理
      if (this.isNeedPagination()) {
        this.sourceData = [...this.rightSourceData];
        this.setPaginationData();
      } else {
        this.sourceData = _.uniqBy(
          [...this.rightSourceData, ...this.allSourceData],
          "code"
        );
      }
    },
    //判断是否需要进行分页
    isNeedPagination() {
      const rightLength = this.formData[this.item.prop].length;
      if (!this.isPagination) {
        return false;
      }
      //左侧不足时
      if (this.allSourceData.length - rightLength < this.searcherPageSize) {
        return false;
      }
      return true;
    },
    setPaginationData(startIndex = 0) {
      // debugger; this.currentPage
      // console.log("处理前this.allSourceData.length="+this.allSourceData.length);
      let endIndex = null;
      if (!startIndex) {
        startIndex = (this.currentPage - 1) * this.searcherPageSize;
      }
      // console.log("this.currentPage="+this.currentPage);
      // console.log("this.pageSize="+this.pageSize+",this.sourceData.length="+this.sourceData.length+",this.rightSourceData.length="+this.rightSourceData.length);
      const dValue =
        this.pageSize - (this.sourceData.length - this.rightSourceData.length);
      // console.log("this.allSourceData.length="+this.allSourceData.length);
      // console.log("startIndex="+startIndex);
      // console.log("dValue="+dValue);

      if (startIndex + dValue <= this.allSourceData.length) {
        endIndex = startIndex + dValue;
      } else {
        endIndex = this.allSourceData.length;
        this.isLastPage = true;
      }
      // console.log("===============startIndex:" + startIndex);
      // console.log("===============endIndex:" + endIndex);
      for (let i = startIndex; i < endIndex; i++) {
        const item = this.allSourceData[i];
        // const index = this.sourceData.findIndex(value => {
        //   return item.code == value.code;
        // });
        // if (index < 0) {
        //   this.sourceData.unshift(item);
        // }
        this.sourceData.push(item);
      }
      // console.log("处理后this.sourceData="+JSON.stringify(this.sourceData));
      const flag = this.isNeedAddValue();
      if (flag) {
        this.setPaginationData(endIndex);
      }
    },
    isNeedAddValue() {
      const dValue = this.sourceData.length - this.selectedData.length;
      // console.log("===============dValue:" + dValue);
      if (dValue < this.searcherPageSize && this.isLastPage) {
        return false;
      }
      if (dValue >= this.searcherPageSize) {
        return false;
      }
      return true;
    },
    leftToPage(type) {
      if (type == "pre") {
        this.isLastPage = false;
        if (this.currentPage == 1) {
          Message.info({ message: "已经是第一页" });
          return;
        } else {
          this.currentPage--;
          this.setDataSource();
        }
      } else if (type == "next") {
        if (this.isLastPage) {
          Message.info({ message: "已经是最后一页" });
          return;
        }

        this.currentPage++;
        this.setDataSource();
      }
    },
    showTooltip(e) {
      const target = e.target;
      if (target.title) return;
      target.title = target.innerText;
    }
  },
  computed: {
    dataSource: function() {
      return this.item.dataSource;
    },
    selectedData: function() {
      return this.formData[this.item.prop];
    },
    searcherPageSize: function() {
      return this.item.pageSize || this.pageSize;
    },
    isPagination: function() {
      return this.item.isPagination === false ? false : true;
    },
    defaultSelectedSource: function() {
      return this.item.defaultSelectedSource || [];
    }
  },
  watch: {
    defaultSelectedSource(newVal) {
      if (newVal) {
        this.rightSourceData = newVal;
      }
    },
    dataSource: {
      handler: function(newVal) {
        if (this.isPagination) {
          this.isLastPage = false;
          this.currentPage = 1;
          //若存在性能的问题替换为使用去重方法的
          // this.allSourceData = [...newVal];
          const sourceData = [...newVal, ...this.rightSourceData];
          this.allSourceData = _.uniqBy(sourceData, "code");

          this.cleanSourceData();
          this.setDataSource();
        } else {
          this.sourceData = newVal;
        }
      },
      deep: true
    }
  },
  mounted() {
    this.rightSourceData = [];
  },
  destroyed() {
    this.rightSourceData = [];
    this.allSourceData = [];
    this.sourceData = [];
  }
};
</script>

<style scoped lang="scss">
.content {
  position: relative;

  .search {
    position: absolute;
    top: 50px;
    z-index: 1;
    //width: calc(50% - 170px);
    width: 40%;
    display: flex;
    padding: 0 15px;

    .el-input {
      flex: 1;
      margin-left: 5px;
    }
  }
}

::v-deep .el-transfer {
  .el-transfer-panel {
    width: calc(50% - 250px);
    height: 500px;
  }

  .el-transfer__button {
    margin-right: 10px;
  }

  .pagination {
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    height: 100%;
    width: 100%;
  }

  .el-transfer-panel__body.is-with-footer {
    height: calc(100% - 50px);
  }

  .el-transfer-panel__body {
    height: calc(100%);
  }

  .el-transfer-panel__list {
    height: calc(100%);
  }

  .pagination {
    display: flex;
  }
}

.searcher ::v-deep .el-transfer-panel:first-child .el-transfer-panel__body {
  padding-top: 50px;
}

::v-deep .el-checkbox-group .el-transfer-panel__list {
  padding-bottom: 0;
  height: calc(100%);
  background-color: aquamarine;
}

::v-deep .is-with-footer {
  .el-transfer-panel__filter {
    display: none;
  }
}

::v-deep .el-checkbox__label {
  overflow: hidden !important;
  word-break: keep-all;
  white-space: nowrap;
  text-overflow: ellipsis;
}
</style>
